package com.jzo2o.health.handler;

import com.jzo2o.api.trade.RefundRecordApi;
import com.jzo2o.api.trade.dto.response.ExecutionResultResDTO;
import com.jzo2o.api.trade.enums.RefundStatusEnum;
import com.jzo2o.common.expcetions.BadRequestException;
import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.health.enums.OrderPayStatusEnum;
import com.jzo2o.health.enums.OrderStatusEnum;
import com.jzo2o.health.mapper.OrdersRefundMapper;
import com.jzo2o.health.model.domain.Orders;
import com.jzo2o.health.model.domain.OrdersRefund;
import com.jzo2o.health.properties.OrdersJobProperties;
import com.jzo2o.health.service.IOrdersService;
import com.jzo2o.health.service.IReservationSettingService;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * 订单相关定时任务
 *
 * @author itcast
 * @create 2023/9/2 16:44
 **/
@Slf4j
@Component
public class OrdersHandler {

    @Resource
    private RefundRecordApi refundRecordApi;
    //解决同级方法调用，事务失效问题
    @Resource
    private OrdersHandler orderHandler;
    @Resource
    private OrdersJobProperties ordersJobProperties;

    /**
     * 支付超时取消订单
     * 每分钟执行一次
     */
    @XxlJob(value = "cancelOverTimePayOrder")
    public void cancelOverTimePayOrder() {

    }


    @Autowired
    private OrdersRefundMapper ordersRefundMapper;
    @Autowired
    private IReservationSettingService reservationSettingService;
    @Autowired
    private IOrdersService ordersService;


    /**
     * 订单退款异步任务
     */
    @XxlJob(value = "handleRefundOrders")
    public void handleRefundOrders() {
        //1.查询退款记录表信息
        List<OrdersRefund> ordersRefunds = ordersRefundMapper.selectList(null);
        for (OrdersRefund ordersRefund : ordersRefunds) {
            //查询订单信息
            Orders orders = ordersService.getById(ordersRefund.getId());
            //2.发起退款调用远程接口
            Integer refundStatus = RefundStatusEnum.FAIL.getCode();
            ExecutionResultResDTO executionResultResDTO = null;
            try {
                executionResultResDTO = refundRecordApi.refundTrading(ordersRefund.getTradingOrderNo(), ordersRefund.getRealPayAmount());
                refundStatus = executionResultResDTO.getRefundStatus();
                if (ObjectUtils.equals(refundStatus, RefundStatusEnum.SENDING.getCode())) {
                    //如果退款申请结束后，依然是退款中状态，则隔3秒后再发一次退款申请就是查询操作
                    Thread.sleep(3000);
                    executionResultResDTO = refundRecordApi.refundTrading(ordersRefund.getTradingOrderNo(), ordersRefund.getRealPayAmount());
                    refundStatus = executionResultResDTO.getRefundStatus();
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new BadRequestException("[退款操作]调用支付服务退款接口失败，待退款记录信息：" + ordersRefund);
            }
            //3.更新订单表的退款相关字段的值 update orders set refund_status=?,refund_no=?,refund_id=? where id=?
            boolean resultForOrder = ordersService.lambdaUpdate()
                    .eq(Orders::getId, ordersRefund.getId())//订单id
                    .set(Orders::getRefundNo, executionResultResDTO.getRefundNo())//支付服务退款订单号
                    .set(Orders::getRefundId, executionResultResDTO.getRefundId())//第三方退款订单号
                    .set(Orders::getOrderStatus, OrderStatusEnum.CLOSED.getStatus())//设置已关闭
                    .set(Orders::getPayStatus, OrderPayStatusEnum.REFUND_SUCCESS.getStatus()) //设置支付状态为已退款
                    .update();
            if (!resultForOrder) {
                throw new DBException("[退款操作]更新订单表失败，待退款记录信息：" + ordersRefund);
            }
            //4.删除待退款记录
            Integer resultForRefund = ordersRefundMapper.deleteById(ordersRefund.getId());
            if (resultForRefund == 0) {
                throw new DBException("[退款操作]删除待退款记录失败，待退款记录信息：" + ordersRefund);
            }
            //5.让当天的预约人数 -1
            reservationSettingService.substract(orders.getReservationDate());

            log.info("[退款处理]退款申请及结果处理成功，待退款记录信息：{}，最终退款状态：{}", ordersRefund, refundStatus);
        }
    }

    /**
     * 订单退款处理
     *
     * @param id                    订单id
     * @param executionResultResDTO 第三方退款信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void refundOrder(Long id, ExecutionResultResDTO executionResultResDTO) {

    }
}
